# Generate 'message-translations.ts'
#
# This file is compiled from the YAMLs found in content/client-messages/*.yaml,
# plus gettext-translated messages we found elsewhere.
import glob
from os import path
import json
import gettext

# Import packages from the website app (AutoPep8 will mess this up, so disable it)
import sys
sys.path.append(path.abspath(path.join(path.dirname(__file__), '..', '..')))  # noqa
from website.yaml_file import YamlFile  # noqa

OUTPUT_FILE = 'static/js/message-translations.ts'

# Every key you add here must also be added to content/client-messages.txt
ADDITIONAL_GETTEXT_KEYS = [
    'level_title',
    'unsaved_class_changes',
    'teacher_welcome',
    'copy_link_to_share',
    'customization_deleted',
    'directly_available',
    'disabled',
    'adventures_restored',
    'multiple_keywords_warning',
    'selected',
    'select_all',
    'one_level_error',
    'adventures_tried',
    'graph_title',
    'errors',
    'adventures_completed',
    'number_of_errors',
    'successful_runs',
    'invitations_sent',
    'invite'
]


def main():
    validate_gettext_hackfile()

    translations = {}
    message_keys = set()

    # Client messages
    for cm_file in sorted(glob.glob('content/client-messages/*.yaml')):
        lang_code = path.splitext(path.basename(cm_file))[0]
        cm = YamlFile.for_file(cm_file).to_dict()

        for key, value in list(cm.items()):
            # Make an array of strings into a single string, joined by newline
            if isinstance(value, list):
                cm[key] = '\n'.join(value)

        translations[lang_code] = cm
        message_keys |= cm.keys()

    # Gettext translations
    for lang, trans in translations.items():
        try:
            translator = gettext.translation('messages', localedir='translations', languages=[lang, 'en'])
            for key in ADDITIONAL_GETTEXT_KEYS:
                trans[key] = translator.gettext(key)
                message_keys.add(key)
        except Exception as e:
            raise RuntimeError(f"Not able to load translations for '{lang}'") from e

    # Write file
    with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
        f.write('// This file has been generated by build-tools/heroku/generate-client-messages.py\n')
        f.write('// DO NOT EDIT\n')
        f.write('\n')
        f.write('export type MessageKey = ' + ' | '.join(f"'{k}'" for k in sorted(message_keys)) + '\n')
        f.write('export const TRANSLATIONS: Record<string, Record<MessageKey, string>> = ' +
                json.dumps(translations, indent=2, sort_keys=True, ensure_ascii=False) + ';\n')


def validate_gettext_hackfile():
    """Check that the client-messages.txt file has keys for each of our "additional" keys.

    If we don't do this, babel will not find the keys when it does an extract.
    """
    filename = path.join(path.dirname(__file__), '..', '..', 'content', 'client-messages.txt')
    with open(filename) as f:
        messages = set(x.strip() for x in f.read().split('\n'))

    oopsie = False

    for additional_key in ADDITIONAL_GETTEXT_KEYS:
        gettext_line = f"gettext('{additional_key}')"
        if gettext_line not in messages:
            oopsie = True
            print(f'Put the following line into content/client-messages.txt:   {gettext_line}')

    if oopsie:
        sys.exit(1)


if __name__ == '__main__':
    main()
